/**
 * 
 */
package com.example.Interceptor;

import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;

import com.example.util.JwtConfig;
import com.example.util.StrKit;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.SignatureException;

/**
 * @author zhangwei
 *
 */
public class MyInterceptor implements HandlerInterceptor{
	private static final Set<String> NOT_INTERCEPT_URI = new HashSet<String>();//不拦截的URI
	
    private static final Logger logger = LoggerFactory.getLogger(MyInterceptor.class);
	
	private JwtConfig jwtConfig = new JwtConfig();
	
	static {
	    NOT_INTERCEPT_URI.add("/");
	    NOT_INTERCEPT_URI.add("/login");
	    NOT_INTERCEPT_URI.add("/static/image/spring-boot.png");
	}
	
	/**
     * 接口执行前
     * 
     * @author: zhangwei
     * @date: 2021年1月15日
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    	printLog(request);
    	String uri = request.getRequestURI();
        if (NOT_INTERCEPT_URI.contains(uri)) {
            return true;
        }
        String token = getCookie(request, "token");
        if(StrKit.isBlank(token)){
            return false;
        }
        
        Claims claims = null;
        try{
            claims = jwtConfig.getTokenClaim(token);
            if(claims == null || jwtConfig.isTokenExpired(claims.getExpiration())){
                throw new SignatureException(jwtConfig.getHeader() + "失效，请重新登录。");
            }
        }catch (Exception e){
            throw new SignatureException(jwtConfig.getHeader() + "失效，请重新登录。");
        }
        return true;
    }
    
    /**
     * 获取cookie
     * 
     * @author: zhangwei
     * @date: 2021年1月30日
     */
    public String getCookie(HttpServletRequest request, String name) {
    	Cookie[] cookies =  request.getCookies();
        if(cookies != null){
            for(Cookie cookie : cookies){
                if(cookie.getName().equals(name)){
                    return cookie.getValue();
                }
            }
        }
        return null;
    }
    
	/**
	 * 打印日志
	 * 
	 * @author: zhangwei
	 * @date: 2021年1月22日
	 */
	public void printLog(HttpServletRequest request) {
		Enumeration<String> enu = request.getParameterNames();
		StringBuilder sb = new StringBuilder();
		while (enu.hasMoreElements()) {
			String paraName = (String) enu.nextElement();
			String value = request.getParameter(paraName);
			if ("password".equals(paraName) || "repassword".equals(paraName)) {
				value = "********";
			}
			sb.append("&" + paraName + "=" + value + " ");
		}
		logger.info("Start ==>> Request IP:[" + getIpAddr(request) + "], Request URL:[" + request.getRequestURI()
				+ "], Request Parameter:[" + sb.toString() + "]");
	}
    
    /**
     * 获取IP
     * 
     * @author: zhangwei
     * @date: 2021年1月22日
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
    
    
    /**
     * 接口执行后
     * 
     * @author: zhangwei
     * @date: 2021年1月15日
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }

}
